<!-- 虚拟 DOM:  -->
本质上就是一个 JS 对象, 通过一个对象来描述了每个 DOM 节点的特征, 
并且通过虚拟 DOM 就能够完整的绘制出对应真实的 DOM,

<!-- 为什么 JS 中能够识别 JSX 呢?  -->
这里其实还得多亏了 babel, 通过 babel 的 react 预设包(@babel/preset-react), 
我们就可以对 JSX 进行转换:  JSX 转为 React.createElement(...)

<!-- 虚拟 DOM 好处 -->
拟 DOM 设计的核心就是用高效的 js 操作, 来减少低性能的 DOM 操作, 
以此来提升网页性能, 然后使用 diff 算法对比新旧虚拟 DOM, 
针对差异之处进行重新构建更新视图, 以此来提高页面性能,
虚拟 DOM 这让我们更关注我们的业务逻辑而非 DOM 操作, 这一点即可大大提升我们的开发效率

1.虚拟 DOM 本质上就是个对象, 对其进行任何操作不会引起页面的绘制
2.一次性更新: 当页面频繁操作时, 不去频繁操作真实 DOM, 
而是构建新的虚拟 DOM 对虚拟 DOM 进行频繁操作, 然后一次性渲染, 
这将大大提高性能(因为操作 DOM 比操作 JS 代价更大, 后面有讲)
3.差异化更新: 当状态改变时, 构建新的虚拟 DOM, 然后使用 diff 算法对比新旧虚拟 DOM,
 针对差异之处进行重新构建更新视图, 这样也能够大大提高页面性能
4.提高开发效率: 虚拟 DOM 本质上就是个对象, 相对于直接操作 DOM 来, 直接操作对象相对来说简单又高效
5.虚拟 DOM 的总损耗等于 虚拟 DOM 增删改 + diff 算法 + 真实 DOM 差异增删改 + 排版与重绘
6.真实 DOM 的总损耗是 真实 DOM 完全增删改 + 排版与重绘
7.简单方便: 如果使用手动操作真实 DOM 来完成页面, 繁琐又容易出错, 在大规模应用下维护起来也很困难
8.性能方面: 使用虚拟 DOM, 能够有效避免真实 DOM 数频繁更新, 减少多次引起重绘与回流, 提高性能
9.跨平台: 虚拟 DOM 本质上就是用一种数据结构来描述界面节点, 
借助虚拟 DOM, 带来了跨平台的能力, 一套代码多端运行, 比如: 小程序、React Native

<!-- 虚拟DOM缺点 -->
1.极致性能: 在一些性能要求极高的应用中, 虚拟 DOM 无法进行针对性的极致优化: 
因为从虚拟 DOM 到更新真实 DOM 之间还需要进行一些额外的计算(比如 diff 算法), 
而这中间就多了一些消耗, 肯定没有直接操作 DOM 来得快
2.首次渲染: 首次渲染大量 DOM 时, 需要将虚拟树转换为实际的 DOM 元素, 
并插入到页面中, 这个过程需要额外的计算和操作, 可能会比直接操作实际 DOM 更慢
3.适用度: 虚拟 DOM 需要在内存中创建和维护一个额外的虚拟树结构, 用于表示页面的状态。
这可能会导致一定的内存消耗增加, 特别是在处理大型或复杂的应用程序时, 
所以虚拟 DOM 更适用于动态或频繁变化的内容, 而对于静态内容 (几乎不会变化的部分), 
虚拟 DOM 的优势可能不明显, 因为它仍然需要进行比较和更新的计算

<!-- 虚拟 DOM 一定会比直接操作真实 DOM 快 -->
1.同样的功能, 在虚拟 DOM 中必须需要进行更多的计算、损耗, 所以从理论上来讲虚拟 DOM 只会更慢, 
但这里其实有个前提, 前提就是操作真实 DOM 的方式要做到最优, 
但是单单这一点对于大部分开发人员来说其实是很难的、而且就算做到了也要耗费很多精力, 同时也会增加维护成本;
2.首次渲染或者所有节点都需要进行更新的时候, 这个时候采用虚拟 DOM 会比直接操作原生 DOM 多一重构建虚拟 DOM 树的操作,
 这会更大的占用内存和延长渲染时间
3.对于频繁更新、删除操作: 直接操作真实 DOM(没有经过优化, 直接操作整个 DOM 树)的情况下,
 虚拟 DOM 也行会更快, 因为相对来说操作 DOM 的消耗会比操作 JS 高
4.得失: 在构建一个实际应用的时候, 出于可维护性的考虑, 我们很难为每一个地方都去做手动优化吗,
 但是呢? 虚拟 DOM 在不需要手动优化的情况下, 却能够给我们带来一系列的优化、同时带来更好的开发体验, 
 当然为此我们也只需要付出一点点性能

总结: 操作真实 DOM 如果能做到最优, 那么必然会比虚拟 DOM 更快, 否则结果就不好说咯

<!-- 为什么操作 DOM 会 JS 代价更大 -->
对比:
访问和修改 DOM 元素需要通过浏览器的底层接口提供的 API 来实现的, 
与直接在内存中操作 JavaScript 对象相比,
 通过浏览器接口进行 DOM 操作涉及到更多的层级和复杂性, 从而导致性能开销增加

DOM 操作引起页面重新渲染和重排, 当对 DOM 元素进行修改时, 
浏览器需要重新计算元素的布局和样式, 并重新渲染整个页面或部分页面。
这个过程称为重排 (reflow) 和重绘 (repaint), 它对于页面的性能和响应时间有一定的影响, 增加了页面的负担和性能开销

总的来说, 由于 DOM 操作涉及到浏览器底层接口、页面重排和重绘等因素, 
相比于操作 JavaScript 对象, 其代价较大, 因此, 在编写网页或应用程序时, 
应尽量减少对 DOM 的频繁操作, 优化 DOM 操作的方式和时机, 以提高性能和用户体验
<!-- 为了减少对 DOM 操作的代价, 可以采取以下优化措施: -->
1.批量操作: 将多个 DOM 操作合并成一个批量操作, 减少页面的重排和重绘次数
2.使用文档片段 (DocumentFragment): 将多个 DOM 元素的操作放在文档片段中, 
然后一次性插入到页面中, 减少页面渲染的次数
3.缓存 DOM 查询结果: 避免多次查询同一个 DOM 元素, 将查询结果缓存在变量中以提高性能。
4.使用事件委托: 将事件处理程序绑定在父元素上, 通过事件冒泡机制处理子元素的事件, 减少事件绑定的数量


